#ifndef XPM_CONTROL_XPM_TERM_DOC_CONTROL_H
#define XPM_CONTROL_XPM_TERM_DOC_CONTROL_H

#include <vector>
#include <algorithm>
#include <string>
#include "model/XpmTermDoc.h"
#include "control/TermFactory.h"

using namespace std;

namespace xpm {
	class DocXmlAccess;

	class XpmTermDocControl {
	public:
		XpmTermDocControl(conex::TermFactory* termFactory);
		~XpmTermDocControl();
		void OpenDoc(string filename );
		int SaveDoc(string filename);
		conex::TermFactory* termFactory();
		//interfaces
		//###################################################
		//interface for add map from a range to a term
		RemainRangePair AddMap(int startpos, int blockpos, wstring text, conex::Term* term);
		//interface for remove map in the doc
		RemainRange RemoveMap(int word_ix, int block_ix);
		//****paste****Add a list of blocks into the document
		void InsertXpmBlocks(int blockpos, int startpos, XpmClipboard * blocks);
		//****copy******get blocks from the selection
		void GetXpmBlocksFromSelection(int start, int end, XpmClipboard * blocks);
		//remove for single character 
		//when the textdocument's contents changed. we need to update the block lists
		//remove for a range
		RemainRangePair RemoveCharsInPosRange(int startpos, int chardRemoved);
		//we need to update the block lists
		RemainRangePair AddCharsInPosRange(int startpos, int charsAdded);
		//this is used for tooltip functiion
		TermRange GetTermRangeFromPos(int pos);
		//interface for selected range
		SelectionRange* selectedRange();
		//get xpmdoc
		XpmTermDoc& xpmdoc();
		//precision find
		//void FindByRange(SelectionRange* range, TermBlocksIter& blockIter, TermIter& termIter);
		//get total maps
		int totalMaps();
		string lang();
		//get current lang
		void setLang(string lang);
		//get current termcontrol
	    conex::TermControl * termControl();
	private:
		SelectionRange _selectedRange;
		XpmTermDoc _doc;
		string _filename;
		DocXmlAccess* _xmlaccess;
		conex::TermFactory* _termFactory;
	};
	inline conex::TermControl* XpmTermDocControl::termControl() {
		return _termFactory->termControl(lang());
	}
	inline string XpmTermDocControl::lang() {
		return _doc.lang();
	}
	inline void XpmTermDocControl::setLang(string lang) {
		_doc.setLang(lang);
	}
	inline conex::TermFactory* XpmTermDocControl::termFactory() {
		return _termFactory;
	}
	inline SelectionRange* XpmTermDocControl::selectedRange() {
		return &_selectedRange;
	}
	inline XpmTermDoc& XpmTermDocControl::xpmdoc() {
		return _doc;
	}
	//interface for add map from a range to a term
	inline RemainRangePair XpmTermDocControl::AddMap(int startpos, int blockpos, wstring text, conex::Term* term) {
		return _doc.AddMap(startpos, blockpos, text, term);
	}
	//interface for remove map in the doc
	inline RemainRange XpmTermDocControl::RemoveMap(int word_ix, int block_ix) {
		return _doc.RemoveMap(word_ix, block_ix);
	}
	//Add a list of blocks into the document
	inline void XpmTermDocControl::InsertXpmBlocks(int blockpos, int startpos,  XpmClipboard* blocks) {
		_doc.InsertXpmBlocksFromClipboard(blockpos, startpos, blocks);
	}
	//get blocks from the selection
	inline void XpmTermDocControl::GetXpmBlocksFromSelection(int start, int end, XpmClipboard* blocks) {
		_doc.GetXpmBlocksFromSelectionToClipboard(start, end, blocks);
	}
	//remove for single character 
	//when the textdocument's contents changed. we need to update the block lists
	//remove for a range
	inline RemainRangePair XpmTermDocControl::RemoveCharsInPosRange(int startpos, int charsRemoved) {
		return _doc.RemoveCharsInPosRange(startpos, charsRemoved);
	}
	//we need to update the block lists
	inline RemainRangePair XpmTermDocControl::AddCharsInPosRange(int startpos, int charsAdded) {
		return _doc.AddCharsInPosRange(startpos, charsAdded);
	}
	//this is used for tooltip functiion
	inline TermRange XpmTermDocControl::GetTermRangeFromPos(int pos) {
		return _doc.GetTermRangeFromPos(pos);
	}
	//precision find
	/*inline void XpmTermDocControl::FindByRange(SelectionRange* range, TermBlocksIter& blockIter, TermIter& termIter) {
		return _doc.FindByRange(range, blockIter, termIter);
	}*/
	// get total maps in doc
	inline int XpmTermDocControl::totalMaps() {
		return _doc.totalMaps();
	}
}
#endif